﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using GameRobot;

namespace GameRobotControl
{
    public class RobotAction
    {
        public RobotBridge _robotBridge;

        public RobotAction(RobotBridge robotbride)
        {
            _robotBridge = robotbride;
        }

        public List<VirtualRobot> LoadRobot(String robotname)
        {
            List<VirtualRobot> listVirRobot = new List<VirtualRobot>();
            foreach (string file in Directory.GetFiles(RobotControlSetting._dllpath + "\\" + robotname + "\\"))
            {
                FileInfo fileinfo = new FileInfo(file);
                if (fileinfo.Extension.Equals(".dll"))
                {
                    VirtualRobot vr = LoadDll(file);
                    if (vr != null)
                        listVirRobot.Add(vr);
                }
            }

            return listVirRobot;
        }

        public VirtualRobot LoadDll(string file)
        {
            VirtualRobot vr = null;
            Type astype = (new VirtualRobot()).GetType();
           // Assembly asm = Assembly.LoadFrom(file);
            Assembly asm = Assembly.LoadFile(file);
            foreach (Type type in asm.GetTypes())
            {
                if (type.Assembly.FullName == astype.Assembly.FullName)
                    continue;
                bool ok = false;
                Type basetype = type.BaseType;
                while (basetype.BaseType != null)
                {
                    if (basetype.Name.Equals("VirtualRobot"))
                    {
                        ok = true;
                        break;
                    }
                    basetype = basetype.BaseType;
                }
                if (ok)
                {
                    //Type t = asm.GetType(type.FullName);
                    //BindingFlags bflags = BindingFlags.DeclaredOnly | BindingFlags.Public
                    //| BindingFlags.NonPublic | BindingFlags.Instance;
                    //// Construct an instance of the type and invoke the member method
                    //Object obj = t.InvokeMember(type.FullName, bflags |
                    //    BindingFlags.CreateInstance, null, null,
                    //    new object[]{
                    //    file}
                    //    );

                    vr = (VirtualRobot)Activator.CreateInstance(type);
                    vr._robotName = type.Name;
                    vr._robotBridge = _robotBridge;
                }
            }

            return vr;
        }

        #region get method
        public void GetBaseFunction(VirtualRobot baserobot, VirtualRobot _virRobot, List<MethodTag> _listMethod)
        {
            Type type = _virRobot.GetType();
            Type basetype = baserobot.GetType();
            MethodInfo[] methodInfos = type.GetMethods();

            for (int i = 0; i < methodInfos.Length; i++)
            {
                if (methodInfos[i].DeclaringType.Name == basetype.Name)
                {
                    if (methodInfos[i].Name.Contains("_sd"))
                    {
                        if (methodInfos[i].ReturnParameter.ParameterType.Name == "Void")
                        {
                            try
                            {
                                ParameterInfo[] parameterInfos = methodInfos[i].GetParameters();
                                for (int j = 0; j < parameterInfos.Length; j++)
                                {
                                    ParameterInfo para = parameterInfos[j];
                                    Type paramtype = para.ParameterType;
                                    object ob = "0";
                                    // kiem tra du lieu dau vao ok
                                    Convert.ChangeType(ob, paramtype);
                                }
                                MethodTag tag = new MethodTag();
                                tag._master = _virRobot;
                                tag._method = methodInfos[i];
                                _listMethod.Add(tag);
                            }
                            catch (Exception)
                            {
                            }
                        }
                    }
                }
            }
        }

        public void GetMetaFunction(VirtualRobot _virRobot, List<MethodTag> _listMethod)
        {
            Type type = _virRobot.GetType();
            MethodInfo[] methodInfos = type.GetMethods();
            for (int i = 0; i < methodInfos.Length; i++)
            {
                if (methodInfos[i].DeclaringType.Name == type.Name)
                {
                    if (methodInfos[i].Name.Contains("_sd"))
                    {
                        if (methodInfos[i].ReturnParameter.ParameterType.Name == "Void")
                        {
                            try
                            {
                                ParameterInfo[] parameterInfos = methodInfos[i].GetParameters();
                                for (int j = 0; j < parameterInfos.Length; j++)
                                {
                                    ParameterInfo para = parameterInfos[j];
                                    Type paramtype = para.ParameterType;
                                    object ob = "0";
                                    // kiem tra du lieu dau vao ok
                                    Convert.ChangeType(ob, paramtype);
                                }
                                MethodTag tag = new MethodTag();
                                tag._master = _virRobot;
                                tag._method = methodInfos[i];
                                _listMethod.Add(tag);
                            }
                            catch (Exception)
                            {
                            }
                        }
                    }
                }
            }
        }
        #endregion

        public virtual void Start()
        {
        }

        public virtual void Action(GameInput gameinput)
        {
        }
    }
}
